package com.cqs.learning.juc;

import com.cqs.learning.concurrent.UnSafeUtil;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

public class Player {
    final String name;
    volatile int hero = -1;
    public static long heroOffset;
    public static Unsafe unsafe;

    public Player(String name) {
        this.name = name;
    }

    static {
        try {
            unsafe = UnSafeUtil.getUnsafe();
            Field heroField = Player.class.getDeclaredField("hero");
            heroOffset = Objects.requireNonNull(UnSafeUtil.getUnsafe()).objectFieldOffset(heroField);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    public boolean compareAndSwapHero(int expert, int hero) {
       return unsafe.compareAndSwapInt(this, heroOffset, expert, hero);
    }

    public static List<Player> randPlays(int size) {
        ArrayList<Player> players = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            players.add(new Player("玩家" + (i + 1)));
        }

        return players;
    }

    public static List<Player> randPlays() {
        return randPlays(5);
    }
}

class PlayerArg implements ArgumentsProvider {
    @Override
    public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
        Stream<Arguments> argumentsStream = Stream.of(Player.randPlays()).map(Arguments::of);
        return argumentsStream;
    }
}